package com.fowo.api.service.handleWork;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.entity.*;
import com.fowo.api.mapper.*;
import com.fowo.api.model.funds.pay.order.FundsPayOrderVo;
import com.fowo.api.service.FundsPayOrderService;
import com.fowo.api.service.LoanNowBalanceService;
import com.fowo.api.service.impl.FundsPayOrderServiceImpl;
import com.fowo.api.sys.annotation.DataActivity;
import com.fowo.api.sys.entity.enums.SysDataActivityAction;
import com.fowo.api.user.model.JwtUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

@Service
@Slf4j
public class FundsPayOrderPaymentServiceImpl implements FundsPayOrderPaymentService{

    @Resource
    private FundsPayOrderServiceImpl fundsPayOrderService;
    @Resource
    private LoanNowBalanceMapper loanNowBalanceMapper;
    @Resource
    private LoanMonthlyBalanceMapper loanMonthlyBalanceMapper;
    @Resource
    private LoanAdvancePaymentMapper loanAdvancePaymentMapper;
    @Resource
    private LogisticsWithdrawMapper logisticsWithdrawMapper;
    @Resource
    private OtherPayablesMapper otherPayablesMapper;
    @Resource
    private PaymentRecordMapper paymentRecordMapper;

    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了付款操作"
    )
    @Transactional
    @Override
    public boolean payment(FundsPayOrderVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        FundsPayOrder entity = fundsPayOrderService.getById(model.getId());
        Assert.notNull(entity,"请款单不存在");
        BigDecimal thisPayment = model.getThisPayment();
        entity.setExchangeRateType(model.getExchangeRateType());
        entity.setExchangeRate(model.getExchangeRate());
        entity.setPaymentDate(model.getPaymentDate());
        entity.setConvertInto(model.getConvertInto());
        entity.setPaymentRemark(model.getPaymentRemark());
        entity.setPaymentAttachment(model.getPaymentAttachment());
        entity.setPaidAmount(entity.getPaidAmount().add(thisPayment));
        entity.setUnpaidAmount(entity.getUnpaidAmount().subtract(thisPayment));
        entity.setStatus("QK03");
        entity.setLastUpdateTime(new Date());
        if (currentUser != null) {
            entity.setLastUpdateUser(currentUser.getUserId());
            entity.setPaymentUser(currentUser.getUserId());
        }
        if (fundsPayOrderService.updateById(entity)) {
            createPaymentRecord(entity,thisPayment);
            updateFundsPayPool(entity);
            return true;
        }
        return false;
    }

    /**
     * 付款记录
     * @param entity
     * @param paidAmount
     */
    public void createPaymentRecord(FundsPayOrder entity,BigDecimal paidAmount){
        PaymentRecord paymentRecord = new PaymentRecord();
        paymentRecord.setParentId(entity.getId());
        paymentRecord.setHandleTime(new Date());
        paymentRecord.setPayment(paidAmount);
        paymentRecord.setPaymentUser(entity.getLastUpdateUser());
        paymentRecord.setPaymentTime(new Date());
        paymentRecord.setRemark(entity.getPaymentRemark());
        paymentRecord.setAttachment(entity.getPaymentAttachment());
        paymentRecordMapper.insert(paymentRecord);
    }

    /**
     * 更新请款池
     * @param entity
     */
    public void updateFundsPayPool(FundsPayOrder entity){
        switch (entity.getCostType()){ //费用类型
            case "FY01":
                switch (entity.getSettlementType()){ //结算方式
                    case "JS01":
                        updateLoanNowBalance(entity);
                        break;
                    case "JS02":
                        updateLoanMonthlyBalance(entity);
                        break;
                }
                break;
            case "FY03":
                updateLoanAdvancePayment(entity);
                break;
            case "FY02":
                updateLogisticsWithdraw(entity);
                break;
            case "FY04":
                updateOtherPayables(entity);
                break;
        }
    }

    /**
     * 更新贷款现结
     * @param entity
     */
    public void updateLoanNowBalance(FundsPayOrder entity){
        LoanNowBalance loanNowBalance = loanNowBalanceMapper.selectOne(Wrappers.lambdaQuery(LoanNowBalance.class)
                .eq(LoanNowBalance::getPurchaseOrderCode,entity.getAssociatedOrder())
        );
        loanNowBalance.setInApplication(entity.getPaymentAmount().subtract(entity.getPaidAmount()));
        loanNowBalance.setActuallyPaid(entity.getPaidAmount());
        loanNowBalance.setUnpaidMoney(loanNowBalance.getAmountPayable().subtract(entity.getPaidAmount()));
        if(entity.getPaymentAmount().compareTo(entity.getPaidAmount()) == 1){
            loanNowBalance.setStatus("30");
        }else {
            loanNowBalance.setStatus("40");
        }
        loanNowBalanceMapper.updateById(loanNowBalance);
    }

    /**
     * 更新贷款月结
     * @param entity
     */
    public void updateLoanMonthlyBalance(FundsPayOrder entity){
        LoanMonthlyBalance loanMonthlyBalance = loanMonthlyBalanceMapper.selectOne(Wrappers.lambdaQuery(LoanMonthlyBalance.class)
                .eq(LoanMonthlyBalance::getPurchaseOrderCode,entity.getAssociatedOrder())
        );
        if(entity.getPaymentAmount().compareTo(entity.getPaidAmount()) == 1){
            loanMonthlyBalance.setStatus("30");
        }else {
            loanMonthlyBalance.setStatus("40");
        }
        loanMonthlyBalanceMapper.updateById(loanMonthlyBalance);
    }

    /**
     * 更新贷款预付款
     * @param entity
     */
    public void updateLoanAdvancePayment(FundsPayOrder entity){
        LoanAdvancePayment loanAdvancePayment = loanAdvancePaymentMapper.selectOne(Wrappers.lambdaQuery(LoanAdvancePayment.class)
                .eq(LoanAdvancePayment::getPurchaseOrderCode,entity.getAssociatedOrder())
        );
        loanAdvancePayment.setInApplication(entity.getPaymentAmount().subtract(entity.getPaidAmount()));
        loanAdvancePayment.setActuallyPaid(entity.getPaidAmount());
        if(entity.getPaymentAmount().compareTo(entity.getPaidAmount()) == 1){
            loanAdvancePayment.setStatus("30");
        }else {
            loanAdvancePayment.setStatus("40");
        }
        loanAdvancePaymentMapper.updateById(loanAdvancePayment);
    }

    /**
     * 更新物流请款
     * @param entity
     */
    public void updateLogisticsWithdraw(FundsPayOrder entity){
        LogisticsWithdraw logisticsWithdraw = logisticsWithdrawMapper.selectOne(Wrappers.lambdaQuery(LogisticsWithdraw.class)
                .eq(LogisticsWithdraw::getInoviceCode,entity.getAssociatedOrder())
        );
        logisticsWithdraw.setInApplication(entity.getPaymentAmount().subtract(entity.getPaidAmount()));
        logisticsWithdraw.setActuallyPaid(entity.getPaidAmount());
        if(entity.getPaymentAmount().compareTo(entity.getPaidAmount()) == 1){
            logisticsWithdraw.setStatus("30");
        }else {
            logisticsWithdraw.setStatus("40");
        }
        logisticsWithdrawMapper.updateById(logisticsWithdraw);
    }

    /**
     * 更新其他应付款
     * @param entity
     */
    public void updateOtherPayables(FundsPayOrder entity){
        OtherPayables otherPayables = otherPayablesMapper.selectOne(Wrappers.lambdaQuery(OtherPayables.class)
                .eq(OtherPayables::getOtherPayablesCode,entity.getAssociatedOrder())
        );
        otherPayables.setInApplication(entity.getPaymentAmount().subtract(entity.getPaidAmount()));
        otherPayables.setActuallyPaid(entity.getPaidAmount());
        if(entity.getPaymentAmount().compareTo(entity.getPaidAmount()) == 1){
            otherPayables.setStatus("30");
        }else {
            otherPayables.setStatus("40");
        }
        otherPayablesMapper.updateById(otherPayables);
    }
}
